﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace SimTank
{
    public partial class SimTankMainWindow : Form
    {
        private Thread SimulatorThread;

        private void SimulateButton_Click(object sender, EventArgs e)
        {
            SimulationProgressBar.Visible = true;
            ProgressTextLabel.Visible = true;
            SimulatorThread = new Thread(new ThreadStart(RunSimulation));
            SimulatorThread.Start();
        }

        public void RunSimulation()
        {
            List<BaseMob> Actors = new List<BaseMob>();

            String UseModel = new String(new char[] {'\0'});
            this.Invoke(new MethodInvoker(delegate
                {
                    UseModel = TankModel.Text;
                }));

            if (UseModel == "Warrior")
            {
                Warrior Player = new Warrior(0);
                Actors.Add(Player);
            }
            else if (UseModel == "Druid")
            {
                Warrior Player = new Warrior(0);
                Actors.Add(Player);
            }
            else if (UseModel == "Death Knight")
            {
                DeathKnight Player = new DeathKnight(0);
                Actors.Add(Player);
            }
            else if (UseModel == "Paladin")
            {
                Warrior Player = new Warrior(0);
                Actors.Add(Player);
            }

            
            Actors[0].SetDefensive(50000, 23.1, 17.1, 0, 5, 8, 31000, 80);
            Actors[0].SetOffensive(1, 4000, 2200, 2800, 11.3, 380);
            Actors[0].SetTracking(true);
            Actors[0].Priority = ParsePriority();

            BaseMob Mob = new BaseMob(1);
            Mob.SetDefensive(-1, 8.00, 14.00, 5.00, 8.00, 0, 11000, 83);
            Mob.SetOffensive(0, 0, 30000, 40000, 0, 250);
            Actors.Add(Mob);
            
            List<TargettedAttack> attackqueue = new List<TargettedAttack>();

            
            

            for (int i = 0; i <= 720000; i++)
            {
                BaseMob.timestamp = i;
                //query each unit to see if it needs to make an attack
                foreach (BaseMob actor in Actors)
                {
                    TargettedAttack newattack = actor.Action();
                    if (newattack.attack != null)
                        attackqueue.Add(newattack);
                }
                //for each attack, hand it to the unit that its targetted to

                while (attackqueue.Count != 0)
                {
                    Actors.Find(
                        delegate(BaseMob unit) { return unit.unitid == attackqueue[0].targetuid; }).Incoming(attackqueue[0].attack, Actors.Find(
                            delegate(BaseMob unit) { return unit.unitid == attackqueue[0].sourceuid; }));
                    attackqueue.RemoveAt(0);
                }

                if (i % 7200 == 00)
                    this.Invoke(new MethodInvoker(delegate
                        {
                            SimulationProgressBar.Value++;
                        }));
                
            }
            this.Invoke(new MethodInvoker(delegate
                {
                    SimulationProgressBar.Value = 0;
                    SimulationProgressBar.Visible = false;
                    ProgressTextLabel.Visible = false;
                }));
        }

        private List<attackQueueObject> ParsePriority()
        {
            List<attackQueueObject> parsedList = new List<attackQueueObject>();

            this.Invoke(new MethodInvoker(delegate
            {
                foreach (ListViewItem definedPriority in PriorityList.Items)
                {
                    parsedList.Add(new attackQueueObject(definedPriority));
                }
            }));
            return parsedList;
        }
    }
}